
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 沈明月
 * Date: 2022-11-27
 * Time: 20:54
 */



//面向对象的三大特性：封装、继承、多态
//封装：（简单来说就是套壳屏蔽细节）
//将数据和操作数据的方法进行有机结合，隐藏对象的属性和实现细节，仅对外公开接口和对象进行交互


//访问限定符：private、default（default不是关键字，表示默认权限，指什么都不加的时候的权限）、protected、public
//private：只能在同一个类里面使用
//default：什么都不加，就是默认权限，只能在同一个包里面使用
//protected：同一个包里面的同一个类、不同的包里面的不同的类、不同的包的子类
//public：（哪里都能访问）同一个包里面的同一个类、不同的包里面的不同的类、不同的包的子类、不同的包的非子类


/*class Student{
    public String name1;
    private String name2;
    public int age;
}
public class KnowledgeTwo {
    public static void main(String[] args) {
        Student student = new Student();
        student.name1 = "张三";
        System.out.println(student.name1);

        //因为name2在Student类里面是被private修饰，只能在Student的类里面使用，所以此处会报错
        //student.name2 = "小宝";
        //System.out.println(student.name2);

        student.age = 10;
        System.out.println(student.age);
    }
}*/





//包：包是对类、接口等封装机制的体现，是一种对类或者接口等很好的组织方式
//在同一个工程中允许存在相同名称的类，只要在不同的包里面就OK

//如何导入包：
//通过java.util.Date导入java.util这个包里面的Date类（以导入java.util.Date类为例）
//使用import语句导入包：import java.util
//（以java.util包里面的类为例）也可以通过import java.util.*来导入（不是把所有的都导入，而是要哪个就导入哪个）
//可以使用import static导入包中静态的方法和字段




//通过java.util.Date导入java.util这个包里面的Date类（以导入java.util.Date类为例）
/*public class KnowledgeTwo {
    public static void main(String[] args) {
        java.util.Date date = new Date();//比较麻烦
    }
}*/


//使用import语句导入包：import java.util
/*
import java.util.Date;
public class KnowledgeTwo {
    public static void main(String[] args) {
        Date date = new Date();
    }
}*/


//（以java.util包里面的类为例）也可以通过import java.util.*来导入（不是把所有的都导入，而是要哪个就导入哪个）
//这中导包的方法容易出现歧义：
//比如：java.util和java.sql里面都有类名为Date的包，那么当这两个包都导入了且刚好调用了Date这个类的时候，编译器无法辨别Date这个类是来自哪个包的，
//所以更加建议指向性更加清晰的上一种做法（相较之）
/*import java.util.*;
public class KnowledgeTwo {
    public static void main(String[] args) {
        Date date = new Date();
        //得到一个毫秒级别的时间戳
        System.out.println(date.getTime());
    }
}*/


//可以使用import static导入包中静态的方法和字段
/*
import static java.lang.Math.*;//把全部的都导进来了
public class KnowledgeTwo {
    public static void main(String[] args) {
        double x = 10;
        double y = 20;
        //double result = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
        double result = sqrt(pow(x,2) + pow(y,2));//加了上面的导包以后，就可以改成这样
        System.out.println(result);

    }
}*/




/*class Person{
    private String name;//通过使用private来修饰，使得name只能在Person类里面使用
    private int age;

    //此时的name和age都是private修饰的成员变量，无法在类外使用，要想对它们进行初始化，可以通过构造方法
    //写构造方法的方法有两种：
    //一种是自己手动加上去
    //还有一种是通过IDEA来自动生成：鼠标右键-->Generate-->Constructor->按住Ctrl的同时点击鼠标左键来勾选自己想要的构造方法里面的参数内容-->点击Ok
    //系统就会自动生成
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }


    //对于已经确定好的成员变量，想要再次修改要怎么办（以name为例）：
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name = name;//this的存在确保了被修改的name是局部变量
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //从上面可知，要修改一个private修饰成员变量要通过set和get，那要手动为每一个需要修改的成员变量写set,get确实是比较繁琐的，在IDEA中有快捷键可以帮助我们
    //通过IDEA来自动生成：鼠标右键-->Generate-->Setter and Getter（也可以单独选其中一个）->按住Ctrl的同时点击鼠标左键来勾选自己想要的构造方法里面的参数内容-->点击Ok


    private void eat(){//通过使用private来修饰，使得name只能在Person类里面使用
        System.out.println("吃饭！");
    }
    public void show(){
        System.out.println(name+" "+age);
    }
}

public class KnowledgeTwo {
    public static void main(String[] args) {
        Person person = new Person("张三",10);
        person.show();//张三 10

        //因为是被private修饰，所以不能在KnowledgeTwo类里面使用
        *//*person.name = "张三";
        person.age = 10;*//*

        person.setName("李四");
        person.setAge(12);
        person.show();//李四 12
    }
}*/



//static

/*class Student{
    public String name;
    public int age;
    public static String classroom = "五教112";
    *//*
    classroom--->静态成员变量/类变量/类成员--->是所有变量所共有的
    name、age--->非静态成员变量/普通成员变量
    *//*
    //静态的成员变量不属于对象，所以不用通过对象的引用来访问（如果通过对象的引用来访问也不会报错，只是会警告。），直接通过类名来访问
    //关于上面这一点的证明就是当你实例化一个对象，想通过对象来引用访问类里面的变量时，编译器的提示里并不会包含静态成员变量

    //构造方法：
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void doClass(){
        System.out.println("上课！");
    }

}

public class KnowledgeTwo {
    public static void main(String[] args) {
        Student student1 = new Student("张三",10);
        Student student2 = new Student("李四",12);
        Student student3 = new Student("王五",14);
        System.out.println("ffffa");


        String student4 = null;
        System.out.println(Student.classroom);//五教112
        //System.out.println(student4.name);//报错
    }
}*/



//成员方法：静态成员方法（类方法）、非静态成员方法

//静态成员方法
//在静态成员方法的内部不能直接调用非静态的成员方法（非静态方法是可以使用静态成员方法的）
//在静态方法内部不能直接使用非静态方法的数据成员
//静态方法里不能this

/**/



//对于静态成员的初始化：
//直接赋值
//默认初始化
//通过get和set方法来初始化
//不建议在构造对象的时候在构造方法中对静态成员初始化
//通过代码块进行赋值



/*class Student{
    public String name;
    public int age;
    public static String classroom = "五教112";
    private static int size = 10;


    public static int getSize() {//此处的static最好不要省略，如果省略的话，就变成了实例代码块，要通过new的对象才能调用
        return size;
    }

    public static void setSize(int size) {//此处的static最好不要省略，如果省略的话，就变成了实例代码块，要通过new的对象才能调用
        Student.size = size;
    }

    //构造方法：
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    {
        this.name = "小民";
        this.age = 20;
        System.out.println("构造代码块！");
    }

    public void doClass(){
        System.out.println(name+"上课！");
    }

    public static void func(){
        System.out.println("静态成员方法！");
    }
}

public class KnowledgeTwo {
    public static void main(String[] args) {
        Student student1 = new Student("张三",10);
        student1.doClass();//张三上课！
        Student.func();//静态成员方法！

        int ret = Student.getSize();
        System.out.println(ret);//10

        Student student2 = new Student("李四",12);
        Student student3 = new Student("王五",14);
    }
}*/





//代码块：普通代码块（非静态代码块）、构造代码块（实例代码块）、静态块（静态代码块）、同步代码块
//普通代码块：定义在方法内部的代码块
//构造代码块：类的里面，方法的外面（一般用来初始化非静态的数据成员）。在调用构造方法之前会先执行实例代码块
//静态代码块：初始化静态成员，或者是做一些准备（最先被执行）
/*class Student{
    public String name;
    public int age;
    public static String classroom = "五教112";

    //构造方法：
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void doClass(){
        System.out.println(name+"上课！");
    }

    static {//静态代码块
        System.out.println("静态成员方法！");
    }
}

public class KnowledgeTwo {
    public static void main(String[] args) {
        Student student1 = new Student("张三",10);
        //Student.func();

        student1.doClass();

        Student student2 = new Student("李四",21);
        //Student.func();
        student2.doClass();

        //静态成员方法！
        //张三上课！
        //李四上课！

    }
}*/

//静态代码块不管生成多少个对象，只会执行一次
//静态成员变量是类的属性，因此在JVM加载类时开辟的空间并初始化的
//如果一个类中包含多个静态代码块，在编译代码时，编译器会按照定义的先后顺序依次执行
//实例代码块只有在创建对象的时候才会执行



/*
class Student{
    public String name;
    public int age;
    public static String classroom = "五教112";

    //构造方法：
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void doClass(){
        System.out.println(name+"上课！");
    }

    public static void func() {//静态代码块
        System.out.println("静态成员方法！");
    }
}

public class KnowledgeTwo {
    public static void main(String[] args) {
        Student student1 = new Student("张三",10);
        Student.func();

        student1.doClass();

        Student student2 = new Student("李四",21);
        Student.func();
        student2.doClass();

        //静态成员方法！
        //张三上课！
        //静态成员方法！
        //李四上课！
    }
}*/




/*class Student{
    public String name;
    public int age;

    //构造方法：
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    {//构造代码块：
        this.name = "小民";
        this.age = 20;
        System.out.println("构造代码块！");
    }

    public void doClass(){
        System.out.println(name+"上课！");
    }

    static {//静态代码块
        System.out.println("静态成员方法！");
    }
    public static void func() {//静态代码块
        System.out.println("静态成员方法！");
    }
}

public class KnowledgeTwo {
    public static void main(String[] args) {
        Student student1 = new Student("张三",10);
        student1.doClass();
    }
}*/
